package com.healthcloud.controller.modules.index;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.healthcloud.dto.res.PatientInstrumentDto;
import com.healthcloud.entity.HlHospitalEntity;
import com.healthcloud.entity.SysOrganiEntity;
import com.healthcloud.entity.testresult.TestresultVo;
import com.healthcloud.service.HlHospitalService;
import com.healthcloud.service.InstrumentInfoService;
import com.healthcloud.service.PpPatientBaseService;
import com.healthcloud.service.TestresultService;
import com.healthcloud.service.hospital.SysOrganiService;
import com.healthcloud.utils.ApiRes;
import com.healthcloud.utils.Constant;
import com.healthcloud.utils.PageParam;
import com.healthcloud.utils.RedisUtils;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Controller
@RequestMapping("/index")
public class IndexController {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private PpPatientBaseService ppPatientBaseService;
    @Autowired
    private SysOrganiService sysOrganiService;
    @Autowired
    private HlHospitalService hlHospitalService;
    @Autowired
    private InstrumentInfoService instrumentInfoService;
    @Autowired
    private TestresultService testresultService;

    @ApiIgnore
    @RequestMapping(value = "/show", method = RequestMethod.GET)
    public String showIndex() {
        Integer type = sysOrganiService.getOrganiType();
        if (type == 1) {
            return "admin/layout_commission";
        } else if (type == 2) {
            return "admin/layout_hospital";
        } else if (type == 3) {
            return "admin/hospital_service_station";
        } else {
            return "admin/layout";
        }
    }

    @ApiOperation(value = "首页接口一",
            notes = "bpTestNum:血压异常 bsTestNum:血糖异常 patientTotal:服务站服务总人数" +
                    "unUseTotal5:5天未使用台数 unUseTotal10:10天未使用台数 unUseTotal15:15天未使用台数" +
                    "useTimes5:5天使用次数 useTimes10:10天使用次数 useTimes15:15天使用次数")
    @RequestMapping(value = "/count1", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes count1() {
        String ids = hlHospitalService.getChildeIds();
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }
        //血压
        Integer bpTestNum = Integer.valueOf(redisUtils.get("bpTestNum1"));
        //血糖
        Integer bsTestNum = Integer.valueOf(redisUtils.get("bsTestNum1"));
        //服务人数
        Integer patientTotal = Integer.valueOf(redisUtils.get("patientTotal"));

        // Integer total = instrumentInfoService.totalByHospitalIds(ids);
        // Integer useTotal5 = instrumentInfoService.useTotalByHospitalIds(ids, 5);
        // Integer useTotal10 = instrumentInfoService.useTotalByHospitalIds(ids, 10);
        // Integer useTotal15 = instrumentInfoService.useTotalByHospitalIds(ids, 15);
        Integer useTimes5 = Integer.valueOf(redisUtils.get("useTimes5"));
        Integer useTimes10 = Integer.valueOf(redisUtils.get("useTimes10"));
        Integer useTimes15 = Integer.valueOf(redisUtils.get("useTimes15"));

        Integer unUseInfo5List = Integer.valueOf(redisUtils.get("unUseInfo5List"));
        Integer unUseInfo10List = Integer.valueOf(redisUtils.get("unUseInfo10List"));
        Integer unUseInfo15List = Integer.valueOf(redisUtils.get("unUseInfo15List"));

        Map<String, Object> data = new HashMap<>();
        data.put("bpTestNum", bpTestNum);
        data.put("bsTestNum", bsTestNum);
        // data.put("unUseTotal5", total-useTotal5);
        // data.put("unUseTotal10", total-useTotal10);
        // data.put("unUseTotal15", total-useTotal15);
        data.put("unUseTotal5", unUseInfo5List != 0 ? unUseInfo5List : 0);
        data.put("unUseTotal10", unUseInfo10List != 0 ? unUseInfo10List : 0);
        data.put("unUseTotal15", unUseInfo15List != 0 ? unUseInfo15List : 0);
        data.put("useTimes5", useTimes5);
        data.put("useTimes10", useTimes10);
        data.put("useTimes15", useTimes15);
        data.put("patientTotal", patientTotal);
        data.put("ids", ids);
        return new ApiRes(data);
    }

    @ApiOperation(value = "列表查询未使用设备")
    @PostMapping(value = "/listUnUseInstrument")
    @ResponseBody
    public ApiRes listUnUseInstrument(PageParam pageParam, @RequestParam("num") Integer num) {
        String ids = hlHospitalService.getChildeIds();
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }

        List<PatientInstrumentDto> allUnUseList = instrumentInfoService.listUnUseInstrument(ids, num);
        List<PatientInstrumentDto> unUseInfoPageList = instrumentInfoService.pageForUnUseInstrument(ids, num, pageParam);

        Map<String, Object> map = new HashMap<>();
        map.put("list", unUseInfoPageList);
        map.put("total", allUnUseList.size());
        return new ApiRes(map);
    }

    @ApiOperation(value = "首页接口二",
            notes = "hospitalName:医院名称 patientTotal:服务人数")
    @RequestMapping(value = "/count2", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes count2() {
        SysOrganiEntity organi = sysOrganiService.getOrgani();
        if (organi == null || Constant.STATION_ORG_TYPE == organi.getType()
                || Constant.HOSPITAL_UNORG_TYPE == organi.getType()) {
            return new ApiRes(false, null, null, "未找到机构");
        }
        Map<String, Object> data = new HashMap<>();
        List list = new ArrayList();
        List<HlHospitalEntity> hospitals = hlHospitalService.getChildesOne(organi.getId());
        for (int i = 0; i < hospitals.size(); i++) {
            HlHospitalEntity hospital = hospitals.get(i);
            List<Long> longs = hlHospitalService.getChildeIds(hospital);
            String ids = Joiner.on(",").join(longs);
            //服务人数
            Integer patientTotal = ppPatientBaseService.totalByHospitalIds(ids);
            Map<String, Object> m = new HashMap<>();
            m.put("hospitalName", hospital.getHospShortName());
            m.put("patientTotal", patientTotal);
            m.put("id", hospital.getId());
            m.put("text", hospital.getHospShortName());
            list.add(m);
        }
        data.put("hospitalPatientTotals", list);
        return new ApiRes(data);
    }

    @ApiOperation(value = "首页接口三",
            notes = "bpTestErrorNum:血压异常人数 bpTestNum:血压测试人数" +
                    "bsBeforeTestErrorNum:餐前血糖异常人数 bsBeforeTestNum:餐前血糖测试人数" +
                    "bsAfterTestErrorNum:餐后血糖异常人数 bsAfterTestNum:餐后血糖测试人数" +
                    "bpError:血压异常分布图 bsError:血糖异常分布图" +
                    "bpNum:高血压人数 bsNum:高血糖人数 bp60Num:60岁以上高血压人数" +
                    "bs60Num:60岁以上高血糖人数 manNum:男人数 womanNum:女人数")
    @RequestMapping(value = "/count3", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes count3(String ids) {
        //获取所有子医院
        if (StringUtils.isEmpty(ids)) {
            ids = hlHospitalService.getChildeIds();
        } else {
            Set<Long> set = new HashSet<>();
            String[] arr = ids.split(",");
            for (String s : arr) {
                HlHospitalEntity hospital = hlHospitalService.queryObject(Long.parseLong(s));
                List<Long> ls = hlHospitalService.getChildeIds(hospital);
                for (Long l : ls) {
                    set.add(l);
                }
            }
            ids = StringUtils.join(set.toArray(), ",");
        }
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }
        Map<String, Object> data = new HashMap<>();

        // 血压未达标总数
        // Integer bpTestErrorNum = ppPatientBaseService.countDiseasesByIdsTest(ids, "104001,104002", null);
        // 2020-07-06 修改统计标准为：血压未达标总数：以最近一次测量的血压值为标准，大于等于135/85算未达标。135或85有一个指标达到就算未达标
        Integer bpTestErrorNum = 0;
        if(StringUtils.isBlank(redisUtils.get("bpTestErrorNum"))){
             bpTestErrorNum = 0;
        }else {
             bpTestErrorNum = Integer.valueOf(redisUtils.get("bpTestErrorNum"));
        }

        Integer bpTestNum = 0;
        if(StringUtils.isNotBlank(redisUtils.get("bpTestNum2"))){
            bpTestNum = Integer.valueOf(redisUtils.get("bpTestNum2"));
        }

        // 餐前血糖未达标总数
        // Integer bsBeforeTestErrorNum = ppPatientBaseService.countDiseasesByIdsTest(ids, "105001", null);
//        List bsBeforeTestErrorList = ppPatientBaseService.listErrorBsIdCards(ids, "105001", 7);
        Integer bsBeforeTestErrorNum = 0;
        if(StringUtils.isNotBlank(redisUtils.get("bsBeforeTestErrorNum"))){
            bsBeforeTestErrorNum = Integer.valueOf(redisUtils.get("bsBeforeTestErrorNum"));
        }


        // Integer bsBeforeTestNum = ppPatientBaseService.coutByIdsTest(ids, "105001");
//        List bsBeforeTestList = ppPatientBaseService.listErrorBsIdCards(ids, "105001", null);
        Integer bsBeforeTestNum = 0;
        if(StringUtils.isNotBlank(redisUtils.get("bsBeforeTestNum"))){
            bsBeforeTestNum = Integer.valueOf(redisUtils.get("bsBeforeTestNum"));
        }

        // Integer bsAfterTestErrorNum = ppPatientBaseService.countDiseasesByIdsTest(ids, "105002", null);
//        List bsAfterTestErrorList = ppPatientBaseService.listErrorBsIdCards(ids, "105002", 10);
        Integer bsAfterTestErrorNum = 0 ;
        if(StringUtils.isNotBlank(redisUtils.get("bsAfterTestErrorNum"))){
            bsAfterTestErrorNum = Integer.valueOf(redisUtils.get("bsAfterTestErrorNum"));
        }

        // Integer bsAfterTestNum = ppPatientBaseService.coutByIdsTest(ids, "105002");
//        List bsAfterTestList = ppPatientBaseService.listErrorBsIdCards(ids, "105002", null);
        Integer bsAfterTestNum = 0;
        if(StringUtils.isNotBlank(redisUtils.get("bsAfterTestNum"))){
            bsAfterTestNum = Integer.valueOf(redisUtils.get("bsAfterTestNum"));
        }

        // 血糖未达标总数 2020-07-06 修改统计标准为：以最近一次测量的血糖值为标准，空腹大于等于7.0，餐后血糖大于等于10算未达标。
        Integer bsTestErrorNum =0;
        if(StringUtils.isNotBlank(redisUtils.get("bsTestErrorNum"))) {
            bsTestErrorNum = Integer.valueOf(redisUtils.get("bsTestErrorNum"));
        }
        // 血糖测量总数
        Integer bsTestNum = 0;
        if(StringUtils.isNotBlank(redisUtils.get("bsTestNum2"))){
            bsTestNum = Integer.valueOf(redisUtils.get("bsTestNum2"));
        }

//        Map<String, Object> bpErrorMap = ppPatientBaseService.countErrorAge(ids, "104001,104002");
//        Map<String, Object> bsErrorMap = ppPatientBaseService.countErrorAge(ids, "105001,105002");

        //结果转换,方便前台显示
        List bpError = JSON.parseArray(redisUtils.get("bpError"));
        List bsError = JSON.parseArray(redisUtils.get("bsError"));
        Integer bpNum = 0;
        if(StringUtils.isNotBlank(redisUtils.get("bpNum"))){
            bpNum = Integer.valueOf(redisUtils.get("bpNum"));
        }
        Integer bsNum = Integer.valueOf(redisUtils.get("bsNum"));
        Integer bp60Num = Integer.valueOf(redisUtils.get("bp60Num"));
        Integer bs60Num = Integer.valueOf(redisUtils.get("bs60Num"));
        Integer manNum = Integer.valueOf(redisUtils.get("manNum"));
        Integer womanNum = Integer.valueOf(redisUtils.get("womanNum"));

        data.put("bpTestErrorNum", bpTestErrorNum); // 血压未达标总数：以最近一次测量的血压值为标准，大于等于135/85算未达标。135或85有一个指标达到就算未达标
        data.put("bpTestNum", bpTestNum); // 血压测量总数
        data.put("bsTestErrorNum", bsTestErrorNum); // 血糖未达标总数
        data.put("bsTestNum", bsTestNum); // 血糖测量总数
        data.put("bsBeforeTestErrorNum", bsBeforeTestErrorNum); // 餐前血糖未达标总数
        data.put("bsBeforeTestNum", bsBeforeTestNum); // 餐前血糖测量总数
        data.put("bsAfterTestErrorNum", bsAfterTestErrorNum); // 餐后血糖未达标总数
        data.put("bsAfterTestNum", bsAfterTestNum); // 餐后血糖测量总数
        data.put("bpError", bpError);
        data.put("bsError", bsError);
        data.put("bpNum", bpNum);
        data.put("bsNum", bsNum);
        data.put("bp60Num", bp60Num);
        data.put("bs60Num", bs60Num);
        data.put("manNum", manNum);
        data.put("womanNum", womanNum);
        data.put("ids", ids);
        return new ApiRes(data);
    }

    private List changeMap(Map<String, Object> errorMap) {
        List list = new ArrayList();
        if (errorMap != null) {
            for (Map.Entry<String, Object> entry : errorMap.entrySet()) {
                Map m = new HashMap();
                m.put("age", entry.getKey());
                m.put("num", entry.getValue() == null ? 0 : entry.getValue());
                list.add(m);
            }
        }
        return list;
    }

    @ApiOperation(value = "异常次数",
            notes = "testItemCodes:" +
                    "血压传104001,104002" +
                    "血糖传105001,105002")
    @RequestMapping(value = "/errorCount", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes errorCount(String testItemCodes) {
        String ids = hlHospitalService.getChildeIds();
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }
        Map<String, Object> data = new HashMap<>();
        // Integer errorNum = ppPatientBaseService.countDiseasesByIdsTest(ids, testItemCodes, null);
        // Integer testNum = ppPatientBaseService.coutByIdsTest(ids, testItemCodes);

        Integer errorNum = 0;
        Integer testNum = 0;

        if (testItemCodes.contains("104")) {
            // 血压
            // 血压未达标总数
            // 2020-07-06 修改统计标准为：血压未达标总数：以最近一次测量的血压值为标准，大于等于135/85算未达标。135或85有一个指标达到就算未达标
            Integer bpTestErrorNum = ppPatientBaseService.countBpErrorNumByIdsTest(ids);
            Integer bpTestNum = ppPatientBaseService.coutByIdsTest(ids, "104001,104002");
            errorNum = bpTestErrorNum;
            testNum = bpTestNum;
        }

        if (testItemCodes.contains("105")) {
            // 血糖
            // 血糖未达标总数 2020-07-06 修改统计标准为：以最近一次测量的血糖值为标准，空腹大于等于7.0，餐后血糖大于等于10算未达标。
            Integer bsTestErrorNum = ppPatientBaseService.countBsErrorNum(ids);
            // 血糖测量总数
            Integer bsTestNum = ppPatientBaseService.countBsNum(ids);
            errorNum = bsTestErrorNum;
            testNum = bsTestNum;
        }

        data.put("errorNum", errorNum);
        data.put("testNum", testNum);
        return new ApiRes(data);
    }

    @ApiOperation(value = "血糖测试列表查询")
    @RequestMapping(value = "/patientTests", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes patientTests(PageParam pageParam, TestresultVo entity) {
        String ids = hlHospitalService.getChildeIds();
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }
        entity.setHospitalIds(ids);
        List list = testresultService.queryPatientTests(entity, pageParam);
        int count = testresultService.queryPatientTestsCount(entity);

        Map map = new HashMap();
        map.put("list", list);
        map.put("total", count);
        return new ApiRes(map);
    }

    @ApiOperation(value = "血压测试列表查询")
    @RequestMapping(value = "/patientBpTests", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes patientBpTests(PageParam pageParam, TestresultVo entity) {
        String ids = hlHospitalService.getChildeIds();
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }
        entity.setHospitalIds(ids);
        List list = testresultService.queryPatientBpTests(entity, pageParam);
        int count = testresultService.queryPatientBpTestsCount(entity);

        Map map = new HashMap();
        map.put("list", list);
        map.put("total", count);
        return new ApiRes(map);
    }

    @ApiOperation(value = "统计当年血压测试正常结果")
    @RequestMapping(value = "/countPatientBpTests", method = RequestMethod.GET)
    @ResponseBody
    public ApiRes countPatientBpTests(@ApiParam(value = "0:全部 1:高血压 2:糖尿病", name = "type")
    @RequestParam(value = "type", required = false) String type) {
        String ids = hlHospitalService.getChildeIds();
        if (StringUtils.isEmpty(ids)) {
            return new ApiRes(false, null, null, "未找到医院信息");
        }
        int count = testresultService.countPatientBpTestsCurrYear(ids,type);

        Map map = new HashMap();
        map.put("count", count);
        return new ApiRes(map);
    }

    @ApiIgnore
    @RequestMapping(value = "/bpAbnormal", method = RequestMethod.GET)
    public String bpAbnormal() {
        return "admin/bpAbnormal";
    }

    @ApiIgnore
    @RequestMapping(value = "/bsAbnormal", method = RequestMethod.GET)
    public String bsAbnormal() {
        return "admin/bsAbnormal";
    }

    @ApiIgnore
    @RequestMapping(value = "/notUseInstrument", method = RequestMethod.GET)
    public String notUseInstrument(
            @ApiParam(required = true, name = "num", value = "num") @RequestParam("num") String num, Model model
    ) {
        model.addAttribute("num", num);
        return "admin/notUseInstrument";
    }

    @ApiOperation(value = "保存面包屑")
    @ResponseBody
    @RequestMapping(value = "/saveBreadLine", method = RequestMethod.POST)
    public ApiRes saveBreadLine(HttpServletRequest request, String breadLine) {
        request.getSession().setAttribute("breadLine", breadLine);
        return ApiRes.SUCCESS;
    }

    @ApiOperation(value = "获取面包屑")
    @ResponseBody
    @RequestMapping(value = "/getBreadLine", method = RequestMethod.POST)
    public ApiRes getBreadLine(HttpServletRequest request) {
        return new ApiRes(request.getSession().getAttribute("breadLine"));
    }
}
